/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.myapp.biz;


import com.myapp.entities.Question;
import com.myapp.entities.Survey;
import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.traversal.DocumentTraversal;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.NodeIterator;

/**
 *
 * @author BAOBAO
 */
public class SurveyBiz {

    /**
     * this method use to get list of Survey
     * @param realPath
     * @param loadFileXml
     * @return array list
     */
    public ArrayList<Survey> getListSurvey(String realPath, String loadFileXml) {
        try {

            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

            DocumentBuilder builder = factory.newDocumentBuilder();
            String path = realPath + loadFileXml;
            Document doc = builder.parse(new File(path));

            return returnSurveys(doc);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * Read into a document and return the result as list
     * @param doc
     * @return an array list of Survey object type
     */
    public ArrayList<Survey> returnSurveys(Document doc) {
        try {
            ArrayList<Survey> lst = new ArrayList<Survey>();
            DocumentTraversal docTraversal = (DocumentTraversal) doc;
            NodeIterator iterator = docTraversal.createNodeIterator(doc.getDocumentElement(), NodeFilter.SHOW_ELEMENT, null, true);
            Node node;
            int count = 0;
            while ((node = iterator.nextNode()) != null) {
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    if (node.getNodeName().equals("survey")) {
                        //Casting a Node to Element type to use getAttribute("String")
                        Element elmSur = (Element) node;
                        //Get all childNodes of 'node'
                        NodeList child = node.getChildNodes();
                        Survey survey = null;
                        //get value of attribute,textcontent in all 'questiont' element
                        for (int i = 0; i < child.getLength(); i++) {

                            if (child.item(i).getNodeName().equalsIgnoreCase("question")) {
                                Element surveyNode = (Element) child.item(i).getParentNode();

                                survey = new Survey();
                                Element elmQues = (Element) surveyNode.getElementsByTagName("question").item(0);

                                survey.setQuestionId(elmQues.getAttribute("id"));
                                
                                survey.setContent(surveyNode.getElementsByTagName("question-content").item(0).getTextContent());

                                NodeList nodes = surveyNode.getElementsByTagName("answer");
                                ArrayList<String> ansList = new ArrayList<String>();
                                for (int j = 0; j < nodes.getLength(); j++) {
                                    ansList.add(nodes.item(j).getTextContent());
                                }
                                survey.setAnsList(ansList);
                                lst.add(survey);
                            }
                        }


                        lst.get(count).setSurveyId(elmSur.getAttribute("id"));
                        lst.get(count).setSurveyStatus(elmSur.getAttribute("status"));
                        lst.get(count).setSurveyName(elmSur.getAttribute("name"));
                        count++;

                    }
                }
            }
            return lst;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }


    /**
     * method used to search an Element in XML file,result is set  values of attribute in element
     * @param realPath
     * @param loadFileXml --name's file XML  to read
     * @param query  --a xpath expression
     * @param surveyId    -- attribute name of survey   
     * @return NodeList
     */
    public NodeList searchElementById(String realPath, String loadFileXml,String query, int surveyId) {

        try {
            String expression= "//surveys/survey["+surveyId+"]"+query;
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            String path = realPath + loadFileXml;
            Document doc = builder.parse(new File(path));
            XPathFactory xpathFactory = XPathFactory.newInstance();
            XPath xpath = xpathFactory.newXPath();
            NodeList nodes = (NodeList) xpath.evaluate(expression, doc, XPathConstants.NODESET);

            
            return nodes;


        } catch (Exception e) {
            e.printStackTrace();
            return null;

        }


    }

    public ArrayList<String> getValueOfNode(String realPath, String loadFileXml,String query,String attributeId){

       try{
        NodeList nodes=this.searchElementById(realPath,loadFileXml,query,1);
        ArrayList<String> arr = new ArrayList<String>();

            for (int i = 0; i < nodes.getLength(); i++) {
                Element element = (Element) nodes.item(i);
                arr.add(element.getAttribute(attributeId));

            }
        return arr;
        }catch(NullPointerException nex){
            nex.printStackTrace();
            return null;
        }
    }

    public void updateElement(ArrayList<String> arr3,String realPath, String loadFileXml,String query, int surveyId) {
        try{
        String expression= "//surveys/survey["+surveyId+"]"+query;
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        String path = realPath + loadFileXml;
        Document doc = builder.parse(new File(path));
        XPathFactory xpathFactory = XPathFactory.newInstance();
        XPath xpath = xpathFactory.newXPath();
        NodeList nodes = (NodeList) xpath.evaluate(expression, doc, XPathConstants.NODESET);




        SurveyBiz surbiz = new SurveyBiz();
        ArrayList<String> arr1 = new ArrayList<String>();//values of answer id
        ArrayList<String> arr2 = new ArrayList<String>();//values of statistic        
        arr1 = surbiz.getValueOfNode(realPath,loadFileXml,query,"id");
        arr2 = surbiz.getValueOfNode(realPath,loadFileXml,query,"statistic");

        for (int i = 0; i < arr1.size(); i++) {
            for (int j = 0; j < arr3.size(); j++) {
                if (arr1.get(i).equalsIgnoreCase(arr3.get(j))) {
                    int st = Integer.parseInt(arr2.get(i)) + 1;
                    arr2.set(i, st + "");
                }
            }
        }

        for (int j= 0; j < arr2.size(); j++) {
             Element element = (Element) nodes.item(j);
             element.setAttribute("statistic", arr2.get(j));
             //JOptionPane.showMessageDialog(null,element.getAttribute("statistic"));
        }

        writeXML(doc,new File(path));
        }catch(Exception ex){ex.printStackTrace();}
    }

    /**
     *
     * @param doc
     * @param realPath
     * @param query
     * @param surveyId
     */
    public void enableSurvey(Document doc,String realPath,String surveyId) throws Exception {
        try {
            String expression= "//surveys/survey";

            XPathFactory xpFactory = XPathFactory.newInstance();
            XPath xp = xpFactory.newXPath();

            NodeList nodes = (NodeList)xp.evaluate(expression, doc, XPathConstants.NODESET);

            Element elem;
            for (int i= 0; i < nodes.getLength(); i++) {
                elem = (Element)nodes.item(i);
                JOptionPane.showMessageDialog(null, surveyId+"-"+elem.getAttribute("id"));
                if (elem.getAttribute("id").equals(surveyId)) {
                    elem.setAttribute("status", "show");
                    JOptionPane.showMessageDialog(null, elem.getAttribute("status"));
                }else{
                    elem.setAttribute("status", "hidden");
                }
            }

            FileOutputStream fos = new FileOutputStream(new File(realPath+"surveys.xml"));
            outputData(doc, fos);
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }
    /**
     * this method writes a DOM document to file
     * @param doc
     */

    public static  void writeXML(Document doc,File f) {
        try{
        Source source=new DOMSource(doc);
        Result result=new StreamResult(f);

        Transformer trans=TransformerFactory.newInstance().newTransformer();
        trans.transform(source, result);

        }catch(TransformerException ex){
            ex.printStackTrace();
        }
    }

    /**
     * 
     * @param doc
     * @param id
     * @param question
     * @param answer
     * @param filePath
     */
    public void createElement(Document doc, String id, Question question, ArrayList<String> answer, String filePath) throws Exception {
        try {
            Element elemSurvey = doc.createElement("survey");
            elemSurvey.setAttribute("id", id);
            elemSurvey.setAttribute("status", "hidden");
            elemSurvey.setAttribute("name", "English survey");
            
            Element elemQuestion = doc.createElement("question");
            elemQuestion.setAttribute("id", question.getId());
            elemQuestion.setAttribute("status", "show");

            Element elemContent = doc.createElement("question-content");
            elemContent.setTextContent(question.getQuestion());

            elemQuestion.appendChild(elemContent);
            for (int i = 0; i < answer.size(); i++) {
                Element elemAns = doc.createElement("answer");
                elemAns.setAttribute("id", String.valueOf(i+1));
                elemAns.setTextContent(answer.get(i).toString());

                elemAns.setAttribute("statistic", "0");
                elemAns.setTextContent(answer.get(i).toString());

                elemQuestion.appendChild(elemAns);
            }

            Element elemComments = doc.createElement("comments");
            
            Element elemComment = doc.createElement("comment");
//            elemComment.setAttribute("id", id);
//            elemComment.setAttribute("studentId", id);
            
            elemComments.appendChild(elemComment);

            elemSurvey.appendChild(elemQuestion);
            elemSurvey.appendChild(elemComments);
            
            doc.getDocumentElement().appendChild(elemSurvey);
            
            File file = new File(filePath);
            
            FileOutputStream fos = new FileOutputStream(file);

            //JOptionPane.showMessageDialog(null, "File name: "+file.getName());
            outputData(doc, fos);
            
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    /**
     *
     * @param doc
     * @param output
     * @throws Exception
     */
    public void outputData(Document doc, OutputStream output) throws Exception {
        try {
            OutputFormat format = new OutputFormat();
            format.setIndenting(true);

            XMLSerializer xs = new XMLSerializer(output, format);

            xs.serialize(doc);

            output.flush();
        } catch (Exception e) {
            throw e;
        }
    }

    public void creatComment(String filePath,int surveyId,String studentId,String content){
        try {

            String expression= "//surveys/survey["+surveyId+"]/comments/comment";
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(new File(filePath));
            XPathFactory xpathFactory = XPathFactory.newInstance();
            XPath xpath = xpathFactory.newXPath();
            NodeList nodes = (NodeList) xpath.evaluate(expression, doc, XPathConstants.NODESET);
            int commentId=nodes.getLength()+1;
            Element elmComments=(Element)nodes.item(0).getParentNode();

            Element elmComment=doc.createElement("comment");
            elmComment.setAttribute("id",commentId+"");
            elmComment.setAttribute("studentId", studentId);
            elmComment.setTextContent(content);
            elmComments.appendChild(elmComment);
            
            writeXML(doc,new File(filePath));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {


    }
}
